#include "WorldCell.h"

#include "../Region.h"

#include "../../Managers/GameManager.h"
#include "../../Renderer/DeferredRenderer.h"

using namespace World;

WorldCell::WorldCell(const Vec3f &position)
{
	data = std::unique_ptr<WorldCellData>(new WorldCellData());
	data->position = position;
	data->pos2d = Vec2i((int)position.x(), (int)position.z());
	data->region = std::make_shared<Region>();
}

WorldCell::~WorldCell()
{
}

void WorldCell::generate()
{
	//For now, based on our altitude, we pick a color
	int altitude = (int)data->position.y(); //We don't need more finegrained height info than int here.

	if(altitude < -150)
		data->color = TCODColor::darkestSky;
	else if(altitude < -100)
		data->color = TCODColor::darkerSky;
	else if(altitude < -80)
		data->color = TCODColor::darkSky;
	else if(altitude < -50)
		data->color = TCODColor::sky;
	else if(altitude < -30)
		data->color = TCODColor::lightSky;
	else if(altitude < -10)
		data->color = TCODColor::lighterSky;
	else if(altitude < 0)
		data->color = TCODColor::lightestSky;
	else if(altitude < 50)
		data->color = TCODColor::green;
	else if(altitude < 100)
		data->color = TCODColor::brass;
	else if(altitude < 130)
		data->color = TCODColor::lightGrey;
	else if(altitude < 150)
		data->color = TCODColor::lighterGrey;
	else
		data->color = TCODColor::lightestGrey;

	if(altitude >= 0)
		data->color3f = Vec3f((float)data->color.r / 255.0f, (float)data->color.g / 255.0f, (float)data->color.b / 255.0f) - ((1.0f - (data->position.y()/200.0f))*0.5f);
	else
		data->color3f = Vec3f((float)data->color.r / 255.0f, (float)data->color.g / 255.0f, (float)data->color.b / 255.0f);
}

void WorldCell::zoom(int world_seed, int world_size, bool canFastTravel)
{
	data->region->generate(world_seed * (data->position.x() + data->position.z()*world_size));
}

void WorldCell::render()
{
	auto g_buffer = GameManager::getSingleton()->getRenderer();

	//Define ground graphics for this cell
	g_buffer->addSymbol(data->pos2d, ' ', 0.0f, false);

	//Foreground shading
	g_buffer->shade(data->pos2d, data->color3f,					DeferredRenderer::RL_FOREGROUND,	DeferredRenderer::RT_DIFFUSE);
	g_buffer->shade(data->pos2d, Vec3f(0.5f, 0.5f, 0.5f),		DeferredRenderer::RL_FOREGROUND,	DeferredRenderer::RT_SPECULAR);

	//Background shading
	g_buffer->shade(data->pos2d, data->color3f,					DeferredRenderer::RL_BACKGROUND,	DeferredRenderer::RT_DIFFUSE);
	g_buffer->shade(data->pos2d, Vec3f(0.5f, 0.5f, 0.5f),		DeferredRenderer::RL_BACKGROUND,	DeferredRenderer::RT_SPECULAR);
	g_buffer->shade(data->pos2d, Vec3f(0.0f, 1.0f, 0.0f),		DeferredRenderer::RL_BACKGROUND,	DeferredRenderer::RT_NORMAL);
	g_buffer->shade(data->pos2d, data->position.y(),												DeferredRenderer::RT_DEPTH);
	g_buffer->shade(data->pos2d, 0.5f,																DeferredRenderer::RT_SHININESS);

	//FOV info
	g_buffer->setMapInfo(data->pos2d, true, true);
}
